home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / test / editor.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-07  |  9.3 KB  |  390 lines

  1. //
  2. // "$Id: editor.cxx,v 1.2 1999/01/07 19:17:53 mike Exp $"
  3. //
  4. // A simple text editor program for the Fast Light Tool Kit (FLTK).
  5. //
  6. // This program is described in Chapter 4 of the FLTK Programmer's Guide.
  7. //
  8. // Copyright 1998-1999 by Bill Spitzak and others.
  9. //
  10. // This library is free software; you can redistribute it and/or
  11. // modify it under the terms of the GNU Library General Public
  12. // License as published by the Free Software Foundation; either
  13. // version 2 of the License, or (at your option) any later version.
  14. //
  15. // This library is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18. // Library General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU Library General Public
  21. // License along with this library; if not, write to the Free Software
  22. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  23. // USA.
  24. //
  25. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  26. //
  27.  
  28. //
  29. // Include necessary headers...
  30. //
  31.  
  32. #include <stdio.h>            // Standard library files
  33. #include <stdlib.h>
  34. #include <string.h>
  35.  
  36. #include <FL/Fl.H>            // Main FLTK header file
  37. #include <FL/Fl_Group.H>        // Fl_Group header file
  38. #include <FL/Fl_Window.H>        // Fl_Window header file
  39. #include <FL/fl_ask.H>            // FLTK convenience functions
  40. #include <FL/fl_file_chooser.H>        // FLTK file chooser
  41. #include <FL/Fl_Menu_Bar.H>        // Fl_Menu_Bar header file
  42. #include <FL/Fl_Input.H>        // Fl_Input header file
  43. #include <FL/Fl_Multiline_Input.H>    // Fl_Multiline_Input header file
  44. #include <FL/Fl_Button.H>        // Fl_Button header file
  45. #include <FL/Fl_Return_Button.H>    // Fl_Return_Button header file
  46.  
  47.  
  48. Fl_Window          *window;
  49. Fl_Menu_Bar        *menubar;
  50. Fl_Multiline_Input *input;
  51. Fl_Window          *replace_dlg;
  52. Fl_Input           *replace_find;
  53. Fl_Input           *replace_with;
  54. Fl_Button          *replace_all;
  55. Fl_Return_Button   *replace_next;
  56. Fl_Button          *replace_cancel;
  57.  
  58. int                changed = 0;
  59. char               filename[1024] = "";
  60. char               search[256] = "";
  61.  
  62.  
  63. void set_changed(int);
  64. void save_cb(void);
  65. void saveas_cb(void);
  66. void find2_cb(void);
  67.  
  68. int check_save(void) {
  69.   if (!changed) return 1;
  70.  
  71.   if (fl_ask("The current file has not been saved.\n"
  72.              "Would you like to save it now?")) {
  73.     // Save the file...
  74.     save_cb();
  75.  
  76.     return !changed;
  77.   }
  78.   else return (1);
  79. }
  80.  
  81. void load_file(char *newfile) {
  82.   FILE *fp;
  83.   char buffer[8192];
  84.   int  nbytes;
  85.   int  pos;
  86.  
  87.   input->value("");
  88.  
  89.   fp = fopen(newfile, "r");
  90.   if (fp != NULL) {
  91.     // Was able to open file; let's read from it...
  92.     strcpy(filename, newfile);
  93.     pos = 0;
  94.  
  95.     while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
  96.       input->replace(pos, pos, buffer, nbytes);
  97.       pos += nbytes;
  98.     }
  99.  
  100.     fclose(fp);
  101.     input->position(0);
  102.     set_changed(0);
  103.   } else {
  104.     // Couldn't open file - say so...
  105.     fl_alert("Unable to open \'%s\' for reading!");
  106.   }
  107. }
  108.  
  109. void save_file(char *newfile) {
  110.   FILE *fp;
  111.  
  112.   fp = fopen(newfile, "w");
  113.   if (fp != NULL) {
  114.     // Was able to create file; let's write to it...
  115.     strcpy(filename, newfile);
  116.  
  117.     if (fwrite(input->value(), 1, input->size(), fp) < 1) {
  118.       fl_alert("Unable to write file!");
  119.       fclose(fp);
  120.       return;
  121.     }
  122.  
  123.     fclose(fp);
  124.     changed = 1;
  125.     set_changed(0);
  126.   } else {
  127.     // Couldn't open file - say so...
  128.     fl_alert("Unable to create \'%s\' for writing!");
  129.   }
  130. }
  131.  
  132. void set_changed(int c) {
  133.   if (c != changed) {
  134.     char title[1024];
  135.     char *slash;
  136.  
  137.     changed = c;
  138.  
  139.     if (filename[0] == '\0') strcpy(title, "Untitled");
  140.     else {
  141.       slash = strrchr(filename, '/');
  142.       if (slash == NULL) slash = strrchr(filename, '\\');
  143.  
  144.       if (slash != NULL) strcpy(title, slash + 1);
  145.       else strcpy(title, filename);
  146.     }
  147.  
  148.     if (changed) strcat(title, " (modified)");
  149.  
  150.     window->label(title);
  151.   }
  152. }
  153.  
  154. void changed_cb(void) {
  155.   set_changed(1);
  156. }
  157.  
  158. void copy_cb(void) {
  159.   input->copy();
  160. }
  161.  
  162. void cut_cb(void) {
  163.   input->copy();
  164.   input->cut();
  165. }
  166.  
  167. void delete_cb(void) {
  168.   input->cut();
  169. }
  170.  
  171. void find_cb(void) {
  172.   const char *val;
  173.  
  174.   val = fl_input("Search String:", search);
  175.   if (val != NULL) {
  176.     // User entered a string - go find it!
  177.     strcpy(search, val);
  178.     find2_cb();
  179.   }
  180. }
  181.  
  182. void find2_cb(void) {
  183.   const char *val, *found;
  184.   int pos;
  185.  
  186.   if (search[0] == '\0') {
  187.     // Search string is blank; get a new one...
  188.     find_cb();
  189.     return;
  190.   }
  191.  
  192.   val   = input->value() + input->mark();
  193.   found = strstr(val, search);
  194.  
  195.   if (found != NULL) {
  196.     // Found a match; update the position and mark...
  197.     pos = input->mark() + found - val;
  198.     input->position(pos, pos + strlen(search));
  199.   }
  200.   else fl_alert("No occurrences of \'%s\' found!", search);
  201. }
  202.  
  203. void new_cb(void) {
  204.   if (changed)
  205.     if (!check_save()) return;
  206.  
  207.   filename[0] = '\0';
  208.   input->value("");
  209.   set_changed(0);
  210. }
  211.  
  212. void open_cb(void) {
  213.   char *newfile;
  214.  
  215.   if (changed)
  216.     if (!check_save()) return;
  217.  
  218.   newfile = fl_file_chooser("Open File?", "*", filename);
  219.   if (newfile != NULL) load_file(newfile);
  220. }
  221.  
  222. void paste_cb(void) {
  223.   Fl::paste(*input);
  224. }
  225.  
  226. void quit_cb(void) {
  227.   if (changed)
  228.     if (!check_save())
  229.       return;
  230.  
  231.   window->hide();
  232. }
  233.  
  234. void replace_cb(void) {
  235.   replace_dlg->show();
  236. }
  237.  
  238. void replace2_cb() {
  239.   const char *find, *val, *found;
  240.   int pos;
  241.  
  242.   find = replace_find->value();
  243.   if (find[0] == '\0') {
  244.     // Search string is blank; get a new one...
  245.     replace_dlg->show();
  246.     return;
  247.   }
  248.  
  249.   replace_dlg->hide();
  250.  
  251.   val   = input->value() + input->position();
  252.   found = strstr(val, find);
  253.  
  254.   if (found != NULL) {
  255.     // Found a match; update the position and replace text...
  256.     pos = input->position() + found - val;
  257.     input->replace(pos, pos + strlen(find), replace_with->value());
  258.     input->position(pos + strlen(replace_with->value()));
  259.   }
  260.   else fl_alert("No occurrences of \'%s\' found!", find);
  261. }
  262.  
  263. void replall_cb() {
  264.   const char *find, *val, *found;
  265.   int pos;
  266.   int times;
  267.  
  268.   find = replace_find->value();
  269.   if (find[0] == '\0') {
  270.     // Search string is blank; get a new one...
  271.     replace_dlg->show();
  272.     return;
  273.   }
  274.  
  275.   replace_dlg->hide();
  276.  
  277.   input->position(0);
  278.   times = 0;
  279.  
  280.   // Loop through the whole string
  281.   do {
  282.     val   = input->value() + input->position();
  283.     found = strstr(val, find);
  284.  
  285.     if (found != NULL) {
  286.       // Found a match; update the position and replace text...
  287.       times ++;
  288.       pos = input->position() + found - val;
  289.       input->replace(pos, pos + strlen(find), replace_with->value());
  290.       input->position(pos + strlen(replace_with->value()));
  291.     }
  292.   } while (found != NULL);
  293.  
  294.   if (times > 0) fl_message("Replaced %d occurrences.", times);
  295.   else fl_alert("No occurrences of \'%s\' found!", find);
  296. }
  297.  
  298. void replcan_cb() {
  299.   replace_dlg->hide();
  300. }
  301.  
  302. void save_cb(void) {
  303.   if (filename[0] == '\0') {
  304.     // No filename - get one!
  305.     saveas_cb();
  306.     return;
  307.   }
  308.   else save_file(filename);
  309. }
  310.  
  311. void saveas_cb(void) {
  312.   char *newfile;
  313.  
  314.   newfile = fl_file_chooser("Save File As?", "*", filename);
  315.   if (newfile != NULL) save_file(newfile);
  316. }
  317.  
  318. void undo_cb(void) {
  319.   input->undo();
  320. }
  321.  
  322. Fl_Menu_Item menuitems[] = {
  323.   { "&File", 0, 0, 0, FL_SUBMENU },
  324.     { "&New",        FL_ALT + 'n', (Fl_Callback *)new_cb },
  325.     { "&Open...",    FL_ALT + 'o', (Fl_Callback *)open_cb, 0, FL_MENU_DIVIDER },
  326.     { "&Save",       FL_ALT + 's', (Fl_Callback *)save_cb },
  327.     { "Save &As...", FL_ALT + FL_SHIFT + 's', (Fl_Callback *)saveas_cb, 0, FL_MENU_DIVIDER },
  328.     { "&Quit", FL_ALT + 'q', (Fl_Callback *)quit_cb },
  329.     { 0 },
  330.  
  331.   { "&Edit", 0, 0, 0, FL_SUBMENU },
  332.     { "&Undo",       FL_ALT + 'z', (Fl_Callback *)undo_cb, 0, FL_MENU_DIVIDER },
  333.     { "Cu&t",        FL_ALT + 'x', (Fl_Callback *)cut_cb },
  334.     { "&Copy",       FL_ALT + 'c', (Fl_Callback *)copy_cb },
  335.     { "&Paste",      FL_ALT + 'v', (Fl_Callback *)paste_cb },
  336.     { "&Delete",     0, (Fl_Callback *)delete_cb },
  337.     { 0 },
  338.  
  339.   { "&Search", 0, 0, 0, FL_SUBMENU },
  340.     { "&Find...",       FL_ALT + 'f', (Fl_Callback *)find_cb },
  341.     { "F&ind Again",    FL_ALT + 'g', (Fl_Callback *)find2_cb },
  342.     { "&Replace...",    FL_ALT + 'r', (Fl_Callback *)replace_cb },
  343.     { "Re&place Again", FL_ALT + 't', (Fl_Callback *)replace2_cb },
  344.     { 0 },
  345.  
  346.   { 0 }
  347. };
  348.  
  349. int main(int argc, char **argv) {
  350.   window = new Fl_Window(640, 480, "Untitled");
  351.     menubar = new Fl_Menu_Bar(0, 0, 640, 30);
  352.     menubar->menu(menuitems);
  353.  
  354.     input = new Fl_Multiline_Input(0, 30, 640, 450);
  355.     input->callback((Fl_Callback *)changed_cb);
  356.     input->when(FL_WHEN_CHANGED);
  357.     input->textfont(FL_COURIER);
  358.   window->end();
  359.   window->resizable(input);
  360.   window->callback((Fl_Callback *)quit_cb);
  361.  
  362.   replace_dlg = new Fl_Window(300, 105, "Replace");
  363.     replace_find = new Fl_Input(70, 10, 210, 25, "Find:");
  364.     replace_find->align(FL_ALIGN_LEFT);
  365.  
  366.     replace_with = new Fl_Input(70, 40, 210, 25, "Replace:");
  367.     replace_with->align(FL_ALIGN_LEFT);
  368.  
  369.     replace_all = new Fl_Button(10, 70, 90, 25, "Replace All");
  370.     replace_all->callback((Fl_Callback *)replall_cb);
  371.  
  372.     replace_next = new Fl_Return_Button(105, 70, 120, 25, "Replace Next");
  373.     replace_next->callback((Fl_Callback *)replace2_cb);
  374.  
  375.     replace_cancel = new Fl_Button(230, 70, 60, 25, "Cancel");
  376.     replace_cancel->callback((Fl_Callback *)replcan_cb);
  377.   replace_dlg->end();
  378.   replace_dlg->set_modal();
  379.  
  380.   window->show(1, argv);
  381.  
  382.   if (argc > 1) load_file(argv[1]);
  383.  
  384.   return Fl::run();
  385. }
  386.  
  387. //
  388. // End of "$Id: editor.cxx,v 1.2 1999/01/07 19:17:53 mike Exp $".
  389. //
  390.